package emulator.util.file;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import emulator.util.ByteHelper;

public class FileInfoSid implements FileInfo {
	private int block_size = -1;
	private int start_address = -1;
	private int data_offset = -1;
	private int song_count = 1;
	private int init_address = 0;
	private int exec_address = 0;
	private int start_song;
	private String title = new String();
	private String author = new String();
	private String year = new String();

	public FileInfoSid(String file_name) {
		File file = new File(file_name);
		block_size = -1;
		start_address = -1;
		data_offset = -1;
		start_song = 1;
		FileInputStream file_stream = null;
		try {
			file_stream = new FileInputStream(file);
			new HeaderReader().readHeader(file_stream);
			block_size = (int)file.length() - data_offset;
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
		finally
		{
			if (file_stream != null)
				try { file_stream.close(); } catch (IOException e) {}
		}
	}

	@Override
	public int getFormat() {
		return FileHelper.FILE_FORMAT_SID;
	}

	@Override
	public int getBlockSize() {
		return block_size;
	}

	@Override
	public int getStartAddress() {
		return start_address;
	}

	@Override
	public FileLoadStrategy getLoadStrategy() {
		return data_offset < 0 ? null : new FileLoadStrategySkipPrefix(data_offset);
	}

	@Override
	public FileSaveStrategy getSaveStrategy() {
		// Not supported.
		return null;
	}

	public int getSongCount() {
		return song_count;
	}

	public int getInitAddress() {
		return init_address;
	}

	public int getExecAddress() {
		return exec_address;
	}

	public int getStartSong() {
		return start_song;
	}

	public String getTitle() {
		return title;
	}

	public String getAuthor() {
		return author;
	}

	public String getYear() {
		return year;
	}
	
	class HeaderReader
	{
	int file_offset = 0;
	
		void readHeader(FileInputStream file_stream) throws IOException
		{
			file_offset = 0;
			skipToPos(file_stream, 4);	// skip header magic
			/* sid_version = */ readWord(file_stream);
			data_offset = readWord(file_stream);
			start_address = readWord(file_stream);
			init_address = readWord(file_stream);
			exec_address = readWord(file_stream);
			song_count  = readWord(file_stream);
			start_song = readWord(file_stream);
			skipToPos(file_stream, 0x16);
			title = readString(file_stream, 32);
			// +36    ``<author>''
			skipToPos(file_stream, 0x36);
			author = readString(file_stream, 32);
			// +56    ``<released>'' (also known as ``<copyright>'')
			skipToPos(file_stream, 0x56);
			year = readString(file_stream, 32);
			if (start_address == 0)
			{
				skipToPos(file_stream, data_offset);
				start_address = ByteHelper.readWord(file_stream);
				data_offset += 2;
			}
		}
		
		private int readWord(FileInputStream file_stream) throws IOException
		{
			int word = ByteHelper.readWordBE(file_stream);
			file_offset += 2;
			return word;
		}
		

		private String readString(FileInputStream file_stream, int str_len) throws IOException {
			String text = "";
			for (int i = 0; i < str_len; i++)
			{
				file_offset++;
				int ch = file_stream.read();
				if (ch <= 0) break;
				text += (char)ch;
			}
			return text;
		}
		
		private void skipToPos(FileInputStream file_stream, int target_pos) throws IOException {
			for (; file_offset < target_pos; file_offset++)
				file_stream.read();
		}

	}
}
